import { JXDef } from '../../conventions/JXCommon';
import { INVALID_VALUE, OBJECT_COPY } from '../../Core/CoreDefine';
import { CURRENCY, ITEM_TYPE, STOREBUYTYPE } from '../Common/Define';
import { L } from '../Common/Language';
import { VIEW_ID } from '../Common/UI';
import { JXLocales } from '../Common/Zh';
import RJXItem from '../Data/RunTime/RunRaw/RJXItem';
import { ObjectWrap } from './../../Core/FrameEx/ES5Ex';
import GameMgr from './GameMgr';
export default class ItemMgr extends ObjectWrap {
	protected static _ins: ItemMgr;
	public static get ins(): ItemMgr {
		if (!this._ins) {
			this._ins = new ItemMgr;
		}
		return this._ins;
	}

	constructor() {
		super();
	}

	/**升级属性 */
	public getEquipLvUpGrowArgs(gorw: number, sLv: number): number {
		let raw = GameMgr.lvUpData.getRaw<SLvUpDataRaw>(sLv);
		return gorw * raw.grow;
	}

	/**装备升级资源消耗 */
	public getEquipLvUpExpend(expend: number, sLv: number): number {
		let raw = GameMgr.lvUpData.getRaw<SLvUpDataRaw>(sLv);
		return expend * raw.moneyUp;
	}

	/**装备出售价格 */
	public getEquipLvUpSale(recycle: number, sLv: number) {
		let raw = GameMgr.lvUpData.getRaw<SLvUpDataRaw>(sLv);
		return recycle * raw.moneySale;
	}

	/**
	 * 测试消耗
	 * @param cost 消耗
	 * @param times 次数
	 * @param notEnoughOpen 不足的时候开启
	 * @param env 环境
	 */
	public testCost(cost: any[] | RJXItem, times: number = 1, notEnoughOpen = false): ItemCostResult {
		let result: ItemCostResult = {}
		let tpl = cost instanceof Array ? RJXItem.tpl(...cost) : cost;
		let item = GameMgr.RBagData.getMegreItems(tpl.id, tpl.type);
		result.cur = item.num;
		result.raw = tpl.raw;
		if (tpl.num > 0) {
			let totalTimes = Math.floor(result.cur / tpl.num);
			result.enough = totalTimes >= times;
			result.need = tpl.num * times;
			result.ext = {
				enoughTimes: Math.max(0, totalTimes),
				enoughCost: Math.max(0, Math.min(totalTimes, times) * tpl.num)
			}
			if (!result.enough) {
				if (notEnoughOpen) {
					GameMgr.jumpToMgr.jumpGoTo(VIEW_ID.currencyFrame, cost, times);
				}
				result.tip = tpl.raw.name + L(JXLocales.currency.not_enough);//tpl.name
			}
			return result;
		}
		else {
			result.enough = true;
			result.need = 0;
			result.ext = {
				enoughTimes: NaN,
				enoughCost: NaN,
			}
			return result;
		}
	}

	public checkHavaHeroCanSync() {
		let allHero = GameMgr.rHeroData.getAllHeros().values<IHeroData>()
		for (let i = 0; i < allHero.length; i++) {
			let hero = allHero[i];
			let isBast = this.checkEquipCanSync(hero);
			if (isBast) {
				return isBast;
			}
		}
		return false;
	}

	public checkEquipCanSync(hero: IHeroData) {
		let allEquip = GameMgr.RBagData.getHeroEquip(hero.tableId);
		let equips = [...allEquip.book, ...allEquip.equip];
		let equipInfo = [0, 0, 0, 0, 0, 0, 0, 0, 0]
		for (let i = 0; i < equips.length; i++) {
			let equip = GameMgr.RBagData.getEquipDataById(equips[i]);
			if (equip.wear != INVALID_VALUE) continue;
			if (equip.quality < 6 && hero.equips.indexOf(equips[i]) === INVALID_VALUE) {
				let num = OBJECT_COPY<number>(equipInfo[equip.quality]);
				num++;
				equipInfo[equip.quality] = num;
			}
		}
		for (let i = 0; i < equipInfo.length; i++) {
			if (equipInfo[i] && equipInfo[i] >= 2) {
				return true;
			}
		}
		return false;
	}

	public checkHaveBoxCanOpen(num: number) {
		let items = []
		let boxOpen = null
		switch (num) {
			case 1: {
				boxOpen = GameMgr.systemConfig.value(JXDef.SYS_CONFIG_KEY.silverBoxOpen);
				break;
			}
			case 2: {
				boxOpen = GameMgr.systemConfig.value(JXDef.SYS_CONFIG_KEY.GoldBoxOpen);
				break;
			}
			case 3: {
				boxOpen = GameMgr.systemConfig.value(JXDef.SYS_CONFIG_KEY.dearBoxOpen);
				break;
			}
		}
		boxOpen.forEach((v, index) => {
			if (v != INVALID_VALUE) {
				let item = this.drawType(v, index);
				if (item) { items.push(item) }
			}
		})

		for (let i = 0; i < items.length; i++) {
			let jxItem = new RJXItem(items[i])
			let result = GameMgr.itemMgr.testCost(jxItem);
			if (result.enough) return result.enough;
		}
		return false;
	}

	protected drawType(v: number, index: number,) {
		let item = null;
		if (index == STOREBUYTYPE.COIN) {
			item = [CURRENCY.GOLD, ITEM_TYPE.CURRENCY, v]
		} else if (index == STOREBUYTYPE.YUSHI) {
			item = [CURRENCY.YUSHI, ITEM_TYPE.CURRENCY, v]
		}
		return item;
	}


	public checkHaveEquipCanLv() {
		let allHero = GameMgr.rHeroData.getAllHeros().values<IHeroData>()
		for (let i = 0; i < allHero.length; i++) {
			let hero = allHero[i];
			let isBast = this.checkHeroEquipCanLvUp(hero);
			if (isBast) {
				return isBast;
			}
		}
		return false;
	}


	public checkHeroEquipCanLvUp(hero: IHeroData) {
		let allEquip = GameMgr.RBagData.getHeroEquip(hero.tableId);
		let equips = [...allEquip.book, ...allEquip.equip];
		for (let i = 0; i < equips.length; i++) {
			let equip = GameMgr.RBagData.getEquipDataById(equips[i]);
			if (equip.itemData.raw.quality >= 5) {
				return true;
			}
		}
		return false;
	}
}
